cranelift(aarch64): share base+index across offset loads via uimm12 amode - #13766
Conversation
…mode When several loads share `base + (extended index)` and differ only by a uimm12-scaled offset, keep `base + index` as one CSE-able value and fold each offset into the load's immediate, so a single `add base, index, uxtw` is reused instead of a per-load `add base, #offset`. A zero offset keeps the single-instruction RegExtended form.
The amode CSE folds constant offsets into load/store immediates and keeps base+index as one add. Single-use cases are neutral (offset moves into the immediate); debug-exceptions sheds 2 instructions by reusing base+index across four offsets.
|
Thanks for this! I'm wary of the duplication being added here though, and amode rules are some of the most sensitive in Cranelift so we ideally want as little duplication as possible. For example the offset=0 rules are duplicates of above rules, and even using |
I have removed the duplication. Also added |
Subscribe to Label ActionDetailsThis issue or pull request has been labeled: "cranelift", "cranelift:area:aarch64", "isle"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
|
This helps remove some duplication, yeah, but this is still effectively a duplication of rule (2), however, and it's also a duplication of 3/4/5 in terms of matching pattern. My thinking is that what you want can be achieved by raising the priority of rule 2 because the premise here is that the static offset should have the highest priority for getting folded into the instruction itself while leaving all other computations in a CSE-able form. |
e36eaf8 to
c648bb4
Compare
It's done! I have replaced the four rules with a single generic highest-priority |
One highest-priority rule folds a non-zero uimm12 offset into the load's immediate (over rules 3-7), so a shared base+index stays one CSE-able value across offsets. Generic over `val`; zero falls through to the reg-folding rules.
c648bb4 to
a694c79
Compare
…mode (bytecodealliance#13766) * cranelift(aarch64): share base+index across offset loads via uimm12 amode When several loads share `base + (extended index)` and differ only by a uimm12-scaled offset, keep `base + index` as one CSE-able value and fold each offset into the load's immediate, so a single `add base, index, uxtw` is reused instead of a per-load `add base, #offset`. A zero offset keeps the single-instruction RegExtended form. * aarch64: update disas precise-output for shared base+index amode The amode CSE folds constant offsets into load/store immediates and keeps base+index as one add. Single-use cases are neutral (offset moves into the immediate); debug-exceptions sheds 2 instructions by reusing base+index across four offsets. * cranelift(aarch64): fold uimm12 offset, keep base+index CSE-able One highest-priority rule folds a non-zero uimm12 offset into the load's immediate (over rules 3-7), so a shared base+index stays one CSE-able value across offsets. Generic over `val`; zero falls through to the reg-folding rules.
When several loads share
base + (extended index)and differ only by auimm12-scaled offset (e.g. fields read through a computed index), AArch64 amode
selection emitted a separate
add base, #offsetper load, defeating CSE of theshared
base + index.This folds the offset into the load's immediate and keeps
base + indexas onevalue, so a single
add base, index, uxtwis materialized and reused. A zerooffset keeps the single-instruction
RegExtendedform, so it isneutral-or-better: a cluster of N such loads drops N address-adds to 1, a lone
load is unchanged.
Tested: new aarch64 precise-output filetest + a stack round-trip runtest
(aarch64/x86_64/s390x); the full aarch64 filetest and runtest suites pass.